//
//	File: OyXMLLog.cpp
//

#include "OyXMLLog.h"
#include <time.h>

static TCHAR* XMLLogTypeString[OyXMLLog::LOGTYPENUM] = { 
	L"Unknow", L"Error", L"Warning", L"Comment", L"Event", L"Debug", L"Message" };
static TCHAR* XMLLogNameSpaceString[OyXMLLog::NAMESPACENUM] = { 
	L"None", L"Engines", L"Game", L"UI", L"Variables" };

OyXMLLog::OyXMLLog()
{
	InitializeCriticalSection(&m_csLogLockAccess);

	m_LogID = 1;

	errno_t err;
	if( (err = _tfopen_s( &m_fpXMLLog, L"OY_XMLLog.log", L"w" )) != 0 )
	{
		char Info[128];
		sprintf_s(Info,"Failed open file : Bin\\OY_XMLLog.log ErrorCode:%u",GetLastError());
		MessageBoxA(NULL,Info,NULL,MB_OK);
		return;
	}

	// XML Head
	_ftprintf_s( m_fpXMLLog, L"<?xml version=\"1.0\"?>\n" );
	_ftprintf_s( m_fpXMLLog, L"<?xml-stylesheet type=\"text/xsl\" href=\"ComplexXSLT.xsl\" ?>\n" );
	_ftprintf_s( m_fpXMLLog, L"\n" );

	_ftprintf_s( m_fpXMLLog, L"<RunTimeLog>\n" );

	WriteLogHeader();
}

OyXMLLog::~OyXMLLog()
{
	Destroy();
}

void OyXMLLog::Destroy()
{
	_ftprintf_s( m_fpXMLLog, L"</RunTimeLog>\n" );
	fflush( m_fpXMLLog );
	fclose( m_fpXMLLog );
	DeleteCriticalSection(&m_csLogLockAccess);
}

void OyXMLLog::WriteLogHeader()
{
	static char buffer[32];

	EnterCriticalSection(&m_csLogLockAccess);

	_ftprintf_s( m_fpXMLLog, L"<LogHeader>\n" );

#if OY_DEBUG_LEVEL == 3
	_ftprintf_s( m_fpXMLLog, L"<OutputLevel>all debugging output (Level 3)</OutputLevel>\n" );
#elif OY_DEBUG_LEVEL == 2
	_ftprintf_s( m_fpXMLLog, L"<OutputLevel>comprehensive debugging output (Level 2)</OutputLevel>\n" );
#elif OY_DEBUG_LEVEL == 1
	_ftprintf_s( m_fpXMLLog, L"<OutputLevel>basic debugging output (Level 1)</OutputLevel>\n" );
#else
	_ftprintf_s( m_fpXMLLog, L"<OutputLevel>no debugging output (Level 0)</OutputLevel>\n" );
#endif	
	_ftprintf_s( m_fpXMLLog, L"<Session>\n" );

	_ftprintf_s( m_fpXMLLog, L"<Started>\n" );

	struct tm pTime;
	time_t ctTime;
	time(&ctTime);
	errno_t err = localtime_s( &pTime, &ctTime );

	_ftprintf_s( m_fpXMLLog, L"<Time>%.2d:%.2d:%.2d</Time>\n", pTime.tm_hour, pTime.tm_min, pTime.tm_sec );  

	_ftprintf_s( m_fpXMLLog, L"<Date>%.4d/%.2d/%.2d</Date>\n", pTime.tm_year+1900, pTime.tm_mon+1, pTime.tm_mday );

	_ftprintf_s( m_fpXMLLog, L"</Started>\n" );

	_ftprintf_s( m_fpXMLLog, L"<Configuration>\n" );
	_ftprintf_s( m_fpXMLLog, L"<Memory>\n" );	

	MEMORYSTATUS M;
	GlobalMemoryStatus(&M);
	_ftprintf_s( m_fpXMLLog, L"Total %d KB physical memory. Available %d KB physical memory.\n", M.dwTotalPhys/1024, M.dwAvailPhys/1024 );
	_ftprintf_s( m_fpXMLLog, L"Total %d KB virtual memory. Available %d KB virtual memory.\n", M.dwTotalVirtual/1024, M.dwAvailVirtual/1024 );

	_ftprintf_s( m_fpXMLLog, L"</Memory>\n" );	
	_ftprintf_s( m_fpXMLLog, L"</Configuration>\n" );

	_ftprintf_s( m_fpXMLLog, L"</Session>\n" );
	_ftprintf_s( m_fpXMLLog, L"</LogHeader>\n" );
	_ftprintf_s( m_fpXMLLog, L"\n" );
	fflush( m_fpXMLLog );

	LeaveCriticalSection(&m_csLogLockAccess);
}

void OyXMLLog::WriteLogEntry( int iEntryType, int iNameSpace,
							const TCHAR* strSourceFile, const TCHAR* strFunction,
							int iSourceLine, const TCHAR* strMessage )
{
	EnterCriticalSection(&m_csLogLockAccess);

	if( _tcslen(strMessage) == 0 )
	{
		LeaveCriticalSection(&m_csLogLockAccess);
		return;
	}

	struct tm pTime;
	time_t ctTime;
	time(&ctTime);
	errno_t err = localtime_s( &pTime, &ctTime );

	_ftprintf_s( m_fpXMLLog, L"<LogEvent id=\"%d\">\n", m_LogID );
	_ftprintf_s( m_fpXMLLog, L"<Type>%s</Type>\n", XMLLogTypeString[iEntryType] );
	_ftprintf_s( m_fpXMLLog, L"<TimeIndex>%.2d:%.2d:%.2d</TimeIndex>\n", pTime.tm_hour, pTime.tm_min, pTime.tm_sec); 
	_ftprintf_s( m_fpXMLLog, L"<NameSpace>%s</NameSpace>\n", XMLLogNameSpaceString[iNameSpace] );
	_ftprintf_s( m_fpXMLLog, L"<File>%s</File>\n", strSourceFile );
	_ftprintf_s( m_fpXMLLog, L"<Function>%s</Function>\n", strFunction );
	_ftprintf_s( m_fpXMLLog, L"<LineNumber>%d</LineNumber>\n", iSourceLine );
	_ftprintf_s( m_fpXMLLog, L"<Message>%s</Message>\n", strMessage );
	_ftprintf_s( m_fpXMLLog, L"</LogEvent>\n" );
	_ftprintf_s( m_fpXMLLog, L"\n" );

	// Flush stcmdream to ensure it is written (incase of a crash, we need log to be up to date)
	fflush( m_fpXMLLog );

	m_LogID++;

	LeaveCriticalSection(&m_csLogLockAccess);
}
